"""
余额服务 - 用户余额管理和交易记录
"""

from datetime import datetime
from typing import List, Optional
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, and_
from decimal import Decimal

from app.models.user import User
from app.models.balance import BalanceTransaction, Balance
from app.schemas.balance import BalanceTransactionCreate


class BalanceService:
    """余额服务类"""
    
    async def get_user_balance(self, db: AsyncSession, user_id: int) -> Decimal:
        """获取用户余额"""
        result = await db.execute(select(Balance).where(Balance.user_id == user_id))
        balance = result.scalar_one_or_none()

        if not balance:
            # 如果没有余额记录，创建一个
            balance = Balance(user_id=user_id, amount=Decimal("0.00"))
            db.add(balance)
            await db.commit()
            await db.refresh(balance)

        return balance.amount
    
    async def check_balance(self, db: AsyncSession, user_id: int, amount: Decimal) -> bool:
        """检查余额是否足够"""
        current_balance = await self.get_user_balance(db, user_id)
        return current_balance >= amount
    
    async def add_balance(self, db: AsyncSession, user_id: int, amount: Decimal,
                         description: str = "余额充值") -> BalanceTransaction:
        """增加余额"""
        if amount <= 0:
            raise ValueError("充值金额必须大于0")

        # 获取或创建余额记录
        result = await db.execute(select(Balance).where(Balance.user_id == user_id))
        balance = result.scalar_one_or_none()

        if not balance:
            balance = Balance(user_id=user_id, amount=Decimal("0.00"))
            db.add(balance)
            await db.flush()  # 确保获得ID

        # 更新余额
        old_balance = balance.amount
        balance.amount += amount
        balance.total_recharged += amount
        balance.updated_at = datetime.utcnow()

        # 创建交易记录
        from app.models.balance import TransactionType
        transaction = BalanceTransaction(
            user_id=user_id,
            amount=amount,
            transaction_type=TransactionType.RECHARGE,
            description=description,
            balance_before=old_balance,
            balance_after=balance.amount
        )

        db.add(transaction)
        await db.commit()
        await db.refresh(transaction)

        return transaction
    
    async def deduct_balance(self, db: AsyncSession, user_id: int, amount: Decimal,
                           description: str = "余额扣除") -> BalanceTransaction:
        """扣除余额"""
        if amount <= 0:
            raise ValueError("扣除金额必须大于0")

        # 检查余额是否足够
        if not await self.check_balance(db, user_id, amount):
            raise ValueError("余额不足")

        # 获取余额记录
        result = await db.execute(select(Balance).where(Balance.user_id == user_id))
        balance = result.scalar_one_or_none()

        if not balance:
            raise ValueError("用户余额记录不存在")

        # 更新余额
        old_balance = balance.amount
        balance.amount -= amount
        balance.total_consumed += amount
        balance.updated_at = datetime.utcnow()

        # 创建交易记录
        from app.models.balance import TransactionType
        transaction = BalanceTransaction(
            user_id=user_id,
            amount=-amount,  # 负数表示扣除
            transaction_type=TransactionType.CONSUME,
            description=description,
            balance_before=old_balance,
            balance_after=balance.amount
        )

        db.add(transaction)
        await db.commit()
        await db.refresh(transaction)

        return transaction
    
    async def get_transaction_history(self, db: AsyncSession, user_id: int, 
                                    limit: int = 50, offset: int = 0) -> List[BalanceTransaction]:
        """获取交易历史"""
        result = await db.execute(
            select(BalanceTransaction)
            .where(BalanceTransaction.user_id == user_id)
            .order_by(BalanceTransaction.created_at.desc())
            .limit(limit)
            .offset(offset)
        )
        return result.scalars().all()
    
    async def get_transaction_by_id(self, db: AsyncSession, transaction_id: int, 
                                  user_id: int) -> Optional[BalanceTransaction]:
        """根据ID获取交易记录"""
        result = await db.execute(
            select(BalanceTransaction).where(
                and_(
                    BalanceTransaction.id == transaction_id,
                    BalanceTransaction.user_id == user_id
                )
            )
        )
        return result.scalar_one_or_none()
    
    async def create_welcome_bonus(self, db: AsyncSession, user_id: int) -> BalanceTransaction:
        """创建注册欢迎奖励"""
        welcome_amount = Decimal("1.00")  # 注册赠送1点余额

        # 获取或创建余额记录
        result = await db.execute(select(Balance).where(Balance.user_id == user_id))
        balance = result.scalar_one_or_none()

        if not balance:
            balance = Balance(user_id=user_id, amount=Decimal("0.00"))
            db.add(balance)
            await db.flush()

        # 更新余额
        old_balance = balance.amount
        balance.amount += welcome_amount
        balance.updated_at = datetime.utcnow()

        # 创建交易记录
        from app.models.balance import TransactionType
        transaction = BalanceTransaction(
            user_id=user_id,
            amount=welcome_amount,
            transaction_type=TransactionType.REGISTER_BONUS,
            description="🎁 注册欢迎奖励",
            balance_before=old_balance,
            balance_after=balance.amount
        )

        db.add(transaction)
        await db.commit()
        await db.refresh(transaction)

        return transaction
    
    async def get_balance_summary(self, db: AsyncSession, user_id: int) -> dict:
        """获取余额摘要信息"""
        current_balance = await self.get_user_balance(db, user_id)
        
        # 获取最近的交易记录
        recent_transactions = await self.get_transaction_history(db, user_id, limit=5)
        
        # 计算总收入和支出
        result = await db.execute(
            select(BalanceTransaction).where(BalanceTransaction.user_id == user_id)
        )
        all_transactions = result.scalars().all()
        
        total_income = sum(t.amount for t in all_transactions if t.amount > 0)
        total_expense = sum(abs(t.amount) for t in all_transactions if t.amount < 0)
        
        return {
            "current_balance": current_balance,
            "total_income": total_income,
            "total_expense": total_expense,
            "transaction_count": len(all_transactions),
            "recent_transactions": recent_transactions
        }
